package com.hxx.widget.richtext.toolbar

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
import androidx.core.view.ViewCompat
import androidx.core.view.marginEnd
import androidx.core.view.marginStart
import androidx.customview.widget.ViewDragHelper
import androidx.customview.widget.ViewDragHelper.STATE_IDLE
import com.hxx.widget.R
import com.hxx.widget.loadFromLayoutId
import kotlinx.android.synthetic.main.widget_layout_seekbar.view.*
import kotlin.math.min

/**
 * 滑动条
 */
class SeekBar @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
    private val TAG = "滑动条"
    private var seekStyle = SeekStyle.percent //默认样式 百分比滑动
    var seekListener: OnSeekChangedListener? = null
    private var pointSize = 0
    private var cachePoints = arrayListOf<Int>() //点 模式下的每个点坐标
    private var halfHotPointOffset = 0 //热点区域，在此范围内为选中点
    private val callback = object : ViewDragHelper.Callback() {
        private var currentPosition: Int = 0
        override fun tryCaptureView(child: View, pointerId: Int): Boolean {
            return child.id == R.id.widget_seek_bar
        }

        override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int {

            val startEdge = paddingStart + child.marginStart
            val endEdge = width - paddingEnd - child.width - child.marginEnd

            val targetLeft = if (startEdge > left) {
                startEdge
            } else min(endEdge, left)

            val fullSeekWidth = endEdge - startEdge
            currentPosition = (targetLeft - paddingStart - child.marginStart) * 100 / fullSeekWidth
            return targetLeft
        }

        override fun onViewDragStateChanged(state: Int) {
            super.onViewDragStateChanged(state)
            if (state == STATE_IDLE) movePercentPosition(currentPosition)
        }

        override fun clampViewPositionVertical(child: View, top: Int, dy: Int): Int {
            return height / 2 - child.height / 2
        }
    }
    private val helper: ViewDragHelper = ViewDragHelper.create(this, callback)

    init {
        loadFromLayoutId(R.layout.widget_layout_seekbar)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        helper.processTouchEvent(event!!)
        if (seekStyle == SeekStyle.percent) return true
        if (event.action == MotionEvent.ACTION_DOWN) {
            val currentX = event.x
            if (currentX >= widget_seek_bar.left && currentX <= widget_seek_bar.right) {
                return true
            }
            cachePoints.forEachIndexed { index, i ->
                if (currentX >= i - halfHotPointOffset && currentX <= halfHotPointOffset + i) {
                    val offset = i - widget_seek_bar.left
                    ViewCompat.offsetLeftAndRight(widget_seek_bar, offset.toInt())
                    seekListener?.onPointChanged(index)
                    return@forEachIndexed
                }
            }
        }
        return true
    }

    /**
     * 更改为点模式 并选中默认索引
     */
    fun applyMaxPoint(maxSize: Int, selectedIndex: Int = 0) {
        pointSize = maxSize
        seekStyle = SeekStyle.point
        cachePoints.clear()
        if (maxSize == 0 || maxSize < selectedIndex) throw Exception("参数设置错误，最大索引不能小于选中索引")
        post {
            val percent = if (maxSize == 1) 1f else selectedIndex / (maxSize - 1f)
            val startEdge = paddingStart + widget_seek_bar.marginStart
            val endEdge = width - paddingEnd - widget_seek_bar.width - widget_seek_bar.marginEnd
            val seekWidth = endEdge - startEdge

            val targetLeft = seekWidth * percent + paddingStart + widget_seek_bar.marginStart
            val currentLeft = widget_seek_bar.left
            val offset = targetLeft - currentLeft
            ViewCompat.offsetLeftAndRight(widget_seek_bar, offset.toInt())
            Log.i(TAG, "applyMaxPoint: 选中百分比:$percent,offset:$offset")

            val duration = if (maxSize == 1) {
                seekWidth
            } else {
                seekWidth / (maxSize - 1)
            }
            for (i in 0 until maxSize) {
                cachePoints.add(i * duration + paddingStart + widget_seek_bar.marginStart)
            }
            halfHotPointOffset = duration / 2
        }
    }

    private fun movePercentPosition(position: Int) {
        if (seekStyle == SeekStyle.percent) {
            seekListener?.onPercentChanged(position)
        } else {
            val currentX = widget_seek_bar.left
            cachePoints.forEachIndexed { index, i ->
                if (currentX >= i - halfHotPointOffset && currentX <= halfHotPointOffset + i) {
                    Log.i(TAG, "movePercentPosition: 当前选中点:$index")
                    val offset = i - currentX
                    ViewCompat.offsetLeftAndRight(widget_seek_bar, offset)
                    seekListener?.onPointChanged(index)
                    return@forEachIndexed
                }
            }
        }
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return helper.shouldInterceptTouchEvent(ev!!)
    }

    /**
     * 滑动条的滑动结果监听
     */
    interface OnSeekChangedListener {
        fun onPercentChanged(percent: Int)
        fun onPointChanged(point: Int)
    }

    /**
     * 滑动模式 百分比或者点
     */
    companion object SeekStyle {
        const val percent = 0
        const val point = 1
    }
}
